package leetcode.pre50;


/**
 * 输入: "   -42"
 * 输出: -42
 * 解释: 第一个非空白字符为 '-', 它是一个负号。
 *      我们尽可能将负号与后面所有连续出现的数字组合起来，最后得到 -42
 * <p>
 * 输入: "4193 with words"
 * 输出: 4193
 * 解释: 转换截止于数字 '3' ，因为它的下一个字符不为数字。
 * <p>
 * 输入: "words and 987"
 * 输出: 0
 * 解释: 第一个非空字符是 'w', 但它不是数字或正、负号。
 * 因此无法执行有效的转换。
 * <p>
 * 输入: "-91283472332"
 * 输出: -2147483648
 * 解释: 数字 "-91283472332" 超过 32 位有符号整数范围。
 *      因此返回 INT_MIN (−231)
 *
 * @date 2019/11/15 0015 下午 12:03
 */
public class Code08_IntegerParseInt {


    /**
     * 通过测试
     */
    public static int myAtoi(String str) {
        if (str == null || str.length() == 0) {
            return 0;
        }
        //去除前后空格
        str = str.trim();
        int len = str.length();
        if (len == 0) return 0;
        int index = 0;
        //判断符号位
        int positive = 1;
        //结果
        int res = 0;
        if (str.charAt(index) < '0' || str.charAt(index) > '9') {
            if (str.charAt(index) == '-') {
                positive = -1;
            } else if (str.charAt(index) != '+') {
                return 0;
            }
            //如果只有符号位
            if (++index == len) return 0;
        }
        //开始
        while (index < len) {
            char c = str.charAt(index);
            //判断是否遇到了非法字符，遇到则提前结束
            if (!digital(c))
                return res;
            //判断如果要再处理c是否溢出
            int next = c - '0';
            if (isBound(res, next, positive)) {
                return positive == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
            }
            //处理结果
            res = res * 10 + positive * next;
            index++;
        }
        return res;
    }

    private static boolean digital(char c) {
        return c >= '0' && c <= '9';
    }

    private static boolean isBound(int cur, int next, int positive) {
        int upBound = Integer.MAX_VALUE % 10;
        int lowBound = Integer.MIN_VALUE % 10;
        if (positive == 1) {
            //上限是 88  /10是8   现在已经是9
            if (cur > Integer.MAX_VALUE / 10)
                return true;
            if (cur == Integer.MAX_VALUE / 10)
                return next > upBound;
        } else {
            //TODO 注意这里传来的next下一个应该是负数
            next = -next;
            //上限是 -88 /10是-8  现在是-9
            if (cur < Integer.MIN_VALUE / 10)
                return true;
            if (cur == Integer.MIN_VALUE / 10)
                //next是负数，如果next < lowBound则溢出
                //如next是-9 ，lowBound是-8，那么会溢出
                return next < lowBound;
        }
        return false;
    }


    public static void main(String[] args) {
//        System.out.println(myAtoi("-42"));
        System.out.println(myAtoi("-2147483649"));
//        System.out.println(myAtoi("+2147483647"));
//        System.out.println(Integer.MAX_VALUE);
    }
}
